<template>
  <div class="role-container">
    <!-- 添加按钮 -->
    <div class="rc-1">
      <el-button v-permission="'add-role'" type="primary" size="medium" @click="showDialog = true">添加角色</el-button>
    </div>
    <div class="rc-2">
      <el-table :data="roleList" style="width: 100%">
        <!-- 角色编辑,正常之间的转换 -->
        <el-table-column prop="name" label="角色" width="180">
          <template v-slot="{ row }">
            <div v-if="row.isEdit">
              <el-input v-model="editForm.name" />
            </div>
            <div v-else>{{ row.name }}</div>
          </template>
        </el-table-column>
        <!-- 角色编辑结束 -->
        <!-- 启用编辑 -->
        <el-table-column prop="state" label="启用" width="180">
          <template slot-scope="{ row }">
            <div v-if="row.isEdit">
              <el-switch
                v-model="editForm.state"
                active-color="#13ce66"
                :active-value="1"
                :inactive-value="0"
              />
            </div>
            <div v-else @click="test(row)">{{ row.state == 1 ? '已启用' : '未启用' }}， </div>
          </template>
        </el-table-column>
        <!-- 启用编辑结束 -->
        <!-- 描述编辑开始 -->
        <el-table-column prop="description" label="描述">
          <!-- vue3的插槽v-slot 新语法，只能放在标签 template上面 -->
          <!-- <template v-slot="{ row }"> -->
          <div slot-scope="{row}">
            <div v-if="row.isEdit">
              <el-input v-model="editForm.description" />
            </div>
            <div v-else>{{ row.description }}</div>
          </div>
        </el-table-column>
        <!-- 描述编辑结束 -->
        <el-table-column fixed="right" label="操作" width="150">
          <!-- 操作的转换 编辑变成确定取消-->
          <template slot-scope="{ row }">
            <template v-if="row.isEdit">
              <el-button type="primary" size="small" @click="editSubmitTmp">确定</el-button>
              <!-- row.isEdit = false取消编辑 -->
              <el-button size="small" @click="row.isEdit = false">取消</el-button>
            </template>
            <template v-else>
              <el-button type="text" size="small" @click="assignPermisionTmp(row.id)">分配权限</el-button>
              <el-button type="text" size="small" @click="editRowTmp(row)">编辑</el-button>
              <el-popconfirm
                title="这是一段内容确定删除吗？"
                @onConfirm="confirm(row.id)"
              >
                <el-button slot="reference" type="text" size="small">删除</el-button>
              </el-popconfirm>
            </template>
          </template>
          <!-- 操作转换完成 -->
        </el-table-column>
      </el-table>
    </div>
    <!-- 页码 -->
    <div class="rc-3">
      <el-pagination
        layout="total,prev, pager, next"
        :total="total"
        :current-page.sync="form.page"
        :page-size="form.pagesize"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 添加角色弹窗 -->
    <el-dialog title="修改密码" :visible.sync="showDialog" :append-to-body="true" @close="close">
      <el-form ref="ruleForm" :model="addForm" :rules="rules">
        <el-form-item label="添加角色" label-width="150px" prop="name">
          <el-input v-model="addForm.name" />
        </el-form-item>
        <el-form-item label="启用" label-width="150px">
          <el-switch
            v-model="addForm.state"
            active-color="#13ce66"
            :active-value="1"
            :inactive-value="0"
          />
        </el-form-item>
        <el-form-item label="角色描述" label-width="150px" prop="description">
          <el-input v-model="addForm.description" type="textarea" placeholder="1-100个字符" />
        </el-form-item>
        <el-form-item label-width="150px">
          <el-button type="primary" @click="submitForm">确认修改</el-button>
          <el-button @click="close">取 消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!--分配权限弹窗 -->
    <el-dialog
      title="分配权限"
      :visible.sync="dialogVisible"
      width="50%"
    >
      <!-- 树形结构 --><!-- props里面就是 告诉tree组件，页面上要展示那个字段， 默认是label字段，是否有子节点通过children去看 -->
      <!-- 级联选择器， 也是要这么配置，就是页面显示的字段要自己配置一下 -->
      <el-tree
        v-if="dialogVisible"
        ref="tree"
        :data="treeList"
        :props="{label: 'name', children: 'children'}"
        default-expand-all
        node-key="id"
        show-checkbox
      />
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="assingPermissionSubmitTmp">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { getRoleListRequest, addRoleRequest, deleteRoleRequest, updateRoleRequest, getRoleDetailRequest, assignPremRequest } from '@/api/role'
import { getPermissionListRequest } from '@/api/permission'
import { transformListToTree } from '@/utils'
export default {
  name: 'Role',
  data() {
    return {
      // 当前点击角色权限id
      currentRoleId: null,
      // 树桩的数据
      treeList: [],
      // 分配权限
      dialogVisible: false,
      // 角色数据
      roleList: [],
      // 页码对象
      form: {
        // 默认页数
        page: 1,
        // 一页数据数
        pagesize: 5
      },
      // 数据总数
      total: 0,
      // 默认弹窗是关闭
      showDialog: false,
      // 下面是新增的对象
      addForm: {
        // 添加角色
        name: '',
        // 角色描述
        description: '',
        // 启用的值,后端返回是0或1
        state: 1
      },
      // 编辑表单数据
      editForm: {
        // 添加角色
        name: '',
        // 角色描述
        description: '',
        // 启用的值,后端返回是0或1
        state: 1
      },
      // 校验规则
      rules: {
        name: [
          { required: true, message: '请输入角色名称', trigger: 'blur' },
          { min: 6, max: 20, message: '名称位数在6-20位', trigger: 'blur' }
        ],
        description: [
          { required: true, message: '请输入角色描述', trigger: 'blur' }
        ]
      }
    }
  },
  created() {
    // 刷新页面
    this.getRoleList()
  },
  methods: {
    // 获取信息,并渲染页面
    async getRoleList() {
      // 请求数据
      const res = await getRoleListRequest(this.form)
      // 接收数据,用于上面渲染页面
      this.roleList = res.data.rows
      // 将total(数据总数),给到上面data的total
      this.total = res.data.total
      // 给每一行的对象添加一个属性,控制每行是否是编辑状态还是展示状态
      this.roleList.forEach(item => {
        this.$set(item, 'isEdit', false)
      })
    },
    // 分页
    handleCurrentChange(val) {
      // 将取到的值给val
      this.form.page = val
      // 拿到val的值后从新去调用接口渲染数据
      this.getRoleList()
    },
    // 关闭事件
    close() {
      // 关闭弹窗
      this.showDialog = false
      // 清空弹窗内容 resetFields饿了吗清除
      this.$refs.ruleForm.resetFields()
    },
    // 确认添加数据发送axios
    submitForm() {
      // 所有检验规则通过以后，在打印
      this.$refs.ruleForm.validate(async(valid) => {
        // 只要进入了这个if分支，表示页面所有校验通过
        if (valid) {
          // 获取数据,并切储存到addForm
          await addRoleRequest(this.addForm)
          // 关闭弹窗
          this.close()
          // 友好提示
          this.$message.success({ message: '新增成功' })
          // 重新渲染,刷新页面
          this.getRoleList()
        }
      })
    },
    // 删除
    delRoleTmp(id) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        console.log(id)
        this.$message({
          type: 'success',
          message: '删除成功!'
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    // 第二种删除
    async confirm(id) {
      try {
        await deleteRoleRequest(id)
        // 下面代码是 删除成功才会执行
        this.$message({
          // 提示删除成功
          type: 'success',
          message: '删除成功'
        })
        // 当我们去删除 最后一页的时候，当最后一页 又只有一条数据的时候，就会有bug
        if (this.roleList.length === 1) {
          // 只要有--的操作，一定会有负数请求
          // this.form.page = 1
          if (this.form.page > 1) {
            // this.form.page = this.form.page - 1
            // this.form.page -= 1
            this.form.page--
          }
        }
        // 刷新页面
        this.getRoleList()
      } catch (err) {
        console.log('删除接口报错')
      }
    },
    // 编辑转换
    editRowTmp(row) {
      // 打开之前,做一个排他思想,讲其他的关掉
      // eslint-disable-next-line no-return-assign
      this.roleList.forEach(item => item.isEdit = false)
      // 添加的新的属性,true是编辑状态
      row.isEdit = true
      // row就是几个普通数据类型,只有一层数据拷贝,可以用展开运算符,若多层对象,就需要使用深拷贝
      this.editForm = { ...row }
    },
    // 发送编辑axios
    async editSubmitTmp() {
      // 获取到数据后渲染到数组
      await updateRoleRequest(this.editForm)
      // 更新成功以后，1.给个提示
      this.$message.success({ message: '更新成功' })
      // 编辑完成返回第一页
      // this.form.page = 1
      // 更新后刷新页面
      this.getRoleList()
    },
    // 分配权限
    assignPermisionTmp(id) {
      // 当前点击角色权限id
      this.currentRoleId = id
      // 刷新页面
      this.getPermissionList()
      // 关闭弹窗
      this.dialogVisible = true
    },
    // 发送分配权限接口
    async getPermissionList() {
      // 请求分配权限的数据
      const res = await getPermissionListRequest()
      // 树桩递归
      this.treeList = transformListToTree(res.data, 0)
      // 请求分配权限的勾选中的权限,已有的权限
      const res1 = await getRoleDetailRequest(this.currentRoleId)
      // 传给树桩结构
      // setCheckedKeys通过 keys 设置目前勾选的节点，使用此方法必须设置 node-key 属性
      this.$refs.tree.setCheckedKeys(res1.data.permIds)
    },
    // 分配权限确定事件
    async assingPermissionSubmitTmp() {
      await assignPremRequest({
        id: this.currentRoleId,
        permIds: this.$refs.tree.getCheckedKeys()
      })
      this.$message.success({ message: '分配权限成功' })
      this.getRoleList()
      this.dialogVisible = false
    }
  }
}

</script>

<style lang="scss" scoped>
.role-container {
  margin: 30px 50px;
  .rc-2 {
    margin: 20px;
  }
  .rc-3 {
    text-align: right;
  }
}
</style>
